package com.godenwater.recv.server.szy206;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.serial.SerialAddress;
import org.apache.mina.transport.serial.SerialConnector;
import org.apache.mina.transport.serial.SerialAddress.DataBits;
import org.apache.mina.transport.serial.SerialAddress.FlowControl;
import org.apache.mina.transport.serial.SerialAddress.Parity;
import org.apache.mina.transport.serial.SerialAddress.StopBits;
import org.apache.mina.transport.socket.DatagramSessionConfig;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.godenwater.core.container.BasicModule;

public class ConnectionManager extends BasicModule {

	private static Logger logger = LoggerFactory
			.getLogger(ConnectionManager.class);

	private static int DEFAULT_SERVER_PORT = 20000;
	// 创建一个非阻塞式的服务端，默认打开一个创建此对象
	private NioSocketAcceptor tcpAcceptor;
	private NioDatagramAcceptor udpAcceptor;// = new NioDatagramAcceptor();

	private IoConnector gsmConnector;// = new SerialConnector();
	private IoConnector pstnConnector;// = new SerialConnector();

	public ConnectionManager() {
		super("Connection Manager");
		// TODO Auto-generated constructor stub
	}

	@Override
	public void start() {
		super.start();
		startTcpListener();
		startUdpListener();
		startGsmListener();
		startPstnListener();
	}

	@Override
	public void stop() {
		super.stop();
		stopTcpListener();
		stopUdpListener();
		stopGsmListener();
		stopPstnListener();
	}

	public boolean isTcpListenerEnabled() {
		return true;
	}

	public int getTcpListenerPort() {
		return DEFAULT_SERVER_PORT;// JiveGlobals.getIntProperty("xmpp.server.socket.port",
		// DEFAULT_SERVER_PORT);
	}

	public void setTcpListenerPort(int port) {
		if (port == getTcpListenerPort()) {
			// Ignore new setting
			return;
		}
		// JiveGlobals.setProperty("xmpp.server.socket.port",
		// String.valueOf(port));
		// Stop the port listener for s2s communication
		stopTcpListener();
		if (isTcpListenerEnabled()) {
			try {
				Thread.sleep(5 * 1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// Start the port listener for s2s communication
			startTcpListener();
		}
	}

	private void startTcpListener() {

		tcpAcceptor = new NioSocketAcceptor();
		int PORT = SzyConfig.getHydroGprsTcpPort();
		System.out.println(">> tcp port " + PORT);
		// The logger, if needed. Commented atm
		DefaultIoFilterChainBuilder chain = tcpAcceptor.getFilterChain();
		// chain.addLast("logger", new LoggingFilter());
		chain.addLast("protocol", new ProtocolCodecFilter(new SzyCodecFactory(
				true)));

		// 增加一个数据处理缓存线程池
		// chain.addLast("dbThreadpool", new
		// ExecutorFilter(Executors.newCachedThreadPool()));

		// LoggingFilter loggingFilter = new LoggingFilter();
		// chain.addLast("logging", loggingFilter);

		tcpAcceptor.setHandler(new ServerDataHandler(SzyServer.getInstance(),
				"GPRS"));
		// 设置读取数据的缓冲区大小
		tcpAcceptor.getSessionConfig().setReadBufferSize(2048); // 针对最大报文的缓冲设置

		// 读写通道30秒内无操作进入空闲状态
		tcpAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);

		SocketSessionConfig dcfg = tcpAcceptor.getSessionConfig();
		dcfg.setReuseAddress(true);

		try {
			tcpAcceptor.bind(new InetSocketAddress(PORT));
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private void stopTcpListener() {
		if (tcpAcceptor != null) {
			System.out.println("正在关闭TCP连接");
			tcpAcceptor.unbind();
			tcpAcceptor = null;
		}
	}

	// ---------------------------------------------

	private void startUdpListener() {

		// if (HydroConfig.getGprsUdpEnabled()) {

		int PORT = SzyConfig.getHydroGprsUdpPort();
		System.out.println(">> udp port " + PORT);
		udpAcceptor = new NioDatagramAcceptor();

		// The logger, if needed. Commented atm
		DefaultIoFilterChainBuilder chain = udpAcceptor.getFilterChain();
		chain.addLast("protocol", new ProtocolCodecFilter(new SzyCodecFactory(
				true)));

		// 增加一个数据处理缓存线程池
		// chain.addLast("dbThreadpool", new
		// ExecutorFilter(Executors.newCachedThreadPool()));

		// chain.addLast("logging", new LoggingFilter());

		udpAcceptor.setHandler(new ServerDataHandler(SzyServer.getInstance(),
				"udp"));
		// 设置读取数据的缓冲区大小
		udpAcceptor.getSessionConfig().setReadBufferSize(2048);
		// 读写通道30秒内无操作进入空闲状态
		udpAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);

		DatagramSessionConfig dcfg = udpAcceptor.getSessionConfig();
		dcfg.setReuseAddress(true);
		try {
			udpAcceptor.bind(new InetSocketAddress(PORT));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// }
	}

	private void stopUdpListener() {
		if (udpAcceptor != null) {
			udpAcceptor.unbind();
			udpAcceptor = null;
		}
	}

	private void startGsmListener() {

		if (SzyConfig.isHydroGsmEnabled()) {
			gsmConnector = new SerialConnector();
			// /dev/ttyS0
			SerialAddress portAddress = new SerialAddress(
					SzyConfig.getHydroGsmSerial(),
					SzyConfig.getHydroGsmBaudRate(), DataBits.DATABITS_8,
					StopBits.BITS_1, Parity.NONE, FlowControl.NONE);

			// ==========================================

			DefaultIoFilterChainBuilder chain = gsmConnector.getFilterChain();
			// chain.addLast("logger", new LoggingFilter());
			chain.addLast("protocol", new ProtocolCodecFilter(
					new SzyCodecFactory(true)));

			// 增加一个数据处理缓存线程池
			// chain.addLast("dbThreadpool", new
			// ExecutorFilter(Executors.newCachedThreadPool()));

			// LoggingFilter loggingFilter = new LoggingFilter();
			// chain.addLast("logging", loggingFilter);

			gsmConnector.setHandler(new ServerDataHandler(SzyServer
					.getInstance(), "COMM"));
			// 设置读取数据的缓冲区大小
			gsmConnector.getSessionConfig().setReadBufferSize(
					SzyConfig.getBufferSize()); // 针对最大报文的缓冲设置

			// 读写通道30秒内无操作进入空闲状态
			gsmConnector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
					40);

			// ===========================================

			try {
				ConnectFuture future = gsmConnector.connect(portAddress);

				future.await();

				// IoSession sessin = future.getSession();

			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void stopGsmListener() {
		if (gsmConnector != null) {
			gsmConnector.dispose();
			gsmConnector = null;
		}
	}

	private void startPstnListener() {
		if (SzyConfig.isHydroPstnEnabled()) {
			pstnConnector = new SerialConnector();
			// /dev/ttyS0
			SerialAddress portAddress = new SerialAddress(
					SzyConfig.getHydroPstnSerial(),
					SzyConfig.getHydroPstnBaudRate(), DataBits.DATABITS_8,
					StopBits.BITS_1, Parity.NONE, FlowControl.NONE);

			// ==========================================

			DefaultIoFilterChainBuilder chain = pstnConnector.getFilterChain();
			// chain.addLast("logger", new LoggingFilter());
			chain.addLast("protocol", new ProtocolCodecFilter(
					new SzyCodecFactory(true)));

			// 增加一个数据处理缓存线程池
			// chain.addLast("dbThreadpool", new
			// ExecutorFilter(Executors.newCachedThreadPool()));

			// LoggingFilter loggingFilter = new LoggingFilter();
			// chain.addLast("logging", loggingFilter);

			pstnConnector.setHandler(new ServerDataHandler(SzyServer
					.getInstance(), "PSTN"));
			// 设置读取数据的缓冲区大小
			pstnConnector.getSessionConfig().setReadBufferSize(
					SzyConfig.getBufferSize()); // 针对最大报文的缓冲设置

			// 读写通道30秒内无操作进入空闲状态
			pstnConnector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
					40);

			// ===========================================

			try {
				ConnectFuture future = pstnConnector.connect(portAddress);

				future.await();

				// IoSession sessin = future.getSession();

			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void stopPstnListener() {
		if (pstnConnector != null) {
			pstnConnector.dispose();
			pstnConnector = null;
		}
	}

	public static void main(String[] args) {
		SerialConnector connector = new SerialConnector();

		DefaultIoFilterChainBuilder chain = connector.getFilterChain();
		chain.addLast("protocol", new ProtocolCodecFilter(new SzyCodecFactory(
				true)));
		LoggingFilter loggingFilter = new LoggingFilter();
		connector.getFilterChain().addLast("logging", loggingFilter);

	}

}
